Working with Binary Columns
Even though XML is purely a text-based markup language, FOR XML still has the capability to generate XML that contains data selected from binary–data-typed columns, such as image, binary, and varbinary. To do this, SQL Server base-64 encodes the data, resulting in a long character string.
To implement this in a query, you add joins from the table Production.Product to Production.ProductProductPhoto and then to Production.ProductPhoto, which contains the varbinary(max)–data-typed ThumbNailPhoto column. Then you add the keywords BINARY BASE64 to the FOR XML clause. Listing 5 illustrates this and also shows the schema generated by the XMLSCHEMA keyword. (Note that the base-64 character data is truncated in the listing for brevity with the character string {...}.)
Listing 5. A SELECT Statement That Uses FOR XML RAW and the BINARY BASE64 Option
SELECT TOP 1 Name, ListPrice, Color, Weight, ThumbNailPhoto
FROM Production.Product [Product]
JOIN Production.ProductProductPhoto PhotoJunction ON
[Product].ProductId = PhotoJunction.ProductId
JOIN Production.ProductPhoto Photo
ON Photo.ProductPhotoId = PhotoJunction.ProductPhotoId
WHERE Name LIKE '%Chain%'
ORDER BY Name
FOR XML RAW('ChainElement'),
ELEMENTS XSINIL,
ROOT('ChainDoc'),
XMLSCHEMA('urn:www-samspublishing-com:examples'),
BINARY BASE64
go
<ChainDoc xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<xsd:schema targetNamespace="urn:www-samspublishing-com:examples"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:sqltypes="http://schemas.microsoft.com/sqlserver/2004/sqltypes"
elementFormDefault="qualified">
<xsd:import
namespace=http://schemas.microsoft.com/sqlserver/2004/sqltypes
schemaLocation="http://schemas.microsoft.com/sqlserver/2004/
sqltypes/sqltypes.xsd"
/>
<xsd:element name="ChainElement">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="Name" nillable="1">
<xsd:simpleType sqltypes:sqlTypeAlias="[AdventureWorks2008].[dbo].[Name]">
<xsd:restriction base="sqltypes:nvarchar" sqltypes:localeId="1033"
sqltypes:sqlCompareOptions="IgnoreCase IgnoreKanaType
IgnoreWidth" sqltypes:sqlSortId="52">
<xsd:maxLength value="50" />
</xsd:restriction>
</xsd:simpleType>
</xsd:element>
<xsd:element name="ListPrice" type="sqltypes:money" nillable="1" />
<xsd:element name="Color" nillable="1">
<xsd:simpleType>
<xsd:restriction base="sqltypes:nvarchar" sqltypes:localeId="1033"
sqltypes:sqlCompareOptions="IgnoreCase IgnoreKanaType
IgnoreWidth" sqltypes:sqlSortId="52">
<xsd:maxLength value="15" />
</xsd:restriction>
</xsd:simpleType>
</xsd:element>
<xsd:element name="Weight" nillable="1">
<xsd:simpleType>
<xsd:restriction base="sqltypes:decimal">
<xsd:totalDigits value="8" />
<xsd:fractionDigits value="2" />
</xsd:restriction>
</xsd:simpleType>
</xsd:element>
<xsd:element
name="ThumbNailPhoto" type="sqltypes:varbinary" nillable="1"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<ChainElement xmlns="urn:www-samspublishing-com:examples">
<Name>Chain</Name>
<ListPrice>20.2400</ListPrice>
<Color>Silver</Color>
<Weight xsi:nil="true" />
<ThumbNailPhoto>R0lGODlhUAAxAPcAAKeamoyLj {...}</ThumbNailPhoto>
</ChainElement>
</ChainDoc>